package com.fbt.transfer.app.driver.http;

import android.content.Context;
import com.fbt.transfer.app.driver.BuildConfig;
import com.fbt.transfer.app.driver.util.JsonUtil;
import com.fbt.transfer.app.driver.util.UserManager;
import java.io.ByteArrayInputStream;
import java.security.KeyStore;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import lombok.Getter;
import okhttp3.OkHttpClient;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.jackson.JacksonConverterFactory;

/**
 * @author tuocoo
 */
public class ApiClient {

    private static volatile Retrofit retrofit = null;
    private static volatile String currentBaseUrl = null;
    private static volatile Context applicationContext = null;

    private ApiClient() {
    }

    public static void init(Context context) {
        if (applicationContext == null) {
            synchronized (ApiClient.class) {
                if (applicationContext == null) {
                    applicationContext = context.getApplicationContext();
                }
            }
        }
    }

  private static Retrofit getClient() {
        if (applicationContext == null) {
            throw new IllegalStateException("ApiClient must be initialized with Context before using");
        }
        String baseUrl = getBaseUrl();
        if (retrofit == null || !baseUrl.equals(currentBaseUrl)) {
            synchronized (ApiClient.class) {
                if (retrofit == null || !baseUrl.equals(currentBaseUrl)) {
                    currentBaseUrl = baseUrl;
                    retrofit = createRetrofitInstance(baseUrl);
                }
            }
        }
        return retrofit;
    }

    private static String getBaseUrl() {
        UserManager userManager = UserManager.getInstance(applicationContext);
        return userManager.isTestEnvironment() ?
            BuildConfig.DEV_BASE_URL :
            BuildConfig.PROD_BASE_URL;
    }

    private static Retrofit createRetrofitInstance(String baseUrl) {
        OkHttpClient.Builder builder = new OkHttpClient.Builder();

        // 配置 SSL Socket Factory 和 Trust Manager
        SSLSocketFactory sslSocketFactory;
        X509TrustManager trustManager;
        try {
            SslContextWrapper sslContextWrapper = getSslContextWrapper(null, null, null);
            sslSocketFactory = sslContextWrapper.getSslSocketFactory();
            trustManager = sslContextWrapper.getTrustManager();
        } catch (Exception e) {
            throw new RuntimeException("Failed to initialize SSL context", e);
        }

        builder.hostnameVerifier((hostname, session) -> true)
            .sslSocketFactory(sslSocketFactory, trustManager)
            .addInterceptor(new CustomerHttpInterceptor());

        HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        builder.addInterceptor(interceptor);
        return new Retrofit.Builder()
            .baseUrl(baseUrl)
            .addConverterFactory(JacksonConverterFactory.create(JsonUtil.getMapper()))
            .client(builder.build())
            .build();
    }

    public static ApiInterface getApiInterface() {
        return getClient().create(ApiInterface.class);
    }

    /**
     * 封装 SSL 上下文逻辑
     */

    @Getter
    private static class SslContextWrapper {

        private final SSLSocketFactory sslSocketFactory;
        private final X509TrustManager trustManager;

        public SslContextWrapper(SSLSocketFactory sslSocketFactory, X509TrustManager trustManager) {
            this.sslSocketFactory = sslSocketFactory;
            this.trustManager = trustManager;
        }
    }

    public static SslContextWrapper getSslContextWrapper(byte[] keyStoreBytes, String keyStorePassword,
        byte[] trustStoreBytes) throws Exception {
        TrustManager[] trustManagers;
        KeyManager[] keyManagers = null;

        if (keyStoreBytes != null && keyStorePassword != null) {
            // 初始化 KeyStore
            KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
            keyStore.load(new ByteArrayInputStream(keyStoreBytes), keyStorePassword.toCharArray());
            KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(
                KeyManagerFactory.getDefaultAlgorithm());
            keyManagerFactory.init(keyStore, keyStorePassword.toCharArray());
            keyManagers = keyManagerFactory.getKeyManagers();
        }

        if (trustStoreBytes != null) {
            // 初始化 TrustStore
            KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
            trustStore.load(new ByteArrayInputStream(trustStoreBytes), null);
            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
                TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init(trustStore);
            trustManagers = trustManagerFactory.getTrustManagers();
        } else {
            // 使用默认的信任管理器
            TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
                TrustManagerFactory.getDefaultAlgorithm());
            trustManagerFactory.init((KeyStore) null);
            trustManagers = trustManagerFactory.getTrustManagers();
        }

        // 初始化 SSLContext
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(keyManagers, trustManagers, new java.security.SecureRandom());

        // 返回 SslContextWrapper
        return new SslContextWrapper(sslContext.getSocketFactory(), (X509TrustManager) trustManagers[0]);
    }
}
